package org.aspire.game;

import org.aspire.math.geom.Dimension;
import org.aspire.math.geom.Dimensioned;
import org.aspire.math.geom.Point;
import org.aspire.math.geom.Positioned;

/******************************************************************************
 * An entity is an object inside a game.
 * 
 * @author JPACarabuena
 *****************************************************************************/
public abstract class Entity implements Dimensioned, Positioned {

	// ========================================================================
	// Constants
	// ========================================================================

	// ========================================================================
	// Static Methods
	// ========================================================================

	// ========================================================================
	// Fields
	// ========================================================================

	/**************************************************************************
	 * The location of the entity in the x and y coordinate system.
	 *************************************************************************/
	private Point location;
	
	/**************************************************************************
	 * The dimension of the entity.
	 *************************************************************************/
	private Dimension dimension;
	
	/**************************************************************************
	 * Integer identification to distinguish entity from each other.
	 *************************************************************************/
	private int id;
	
	/**************************************************************************
	 * The z-layer of this entity. This represents the depth of the entity
	 * when the renderer draws it into the screen.
	 *************************************************************************/
	private int layer;
	
	/**************************************************************************
	 * Whether or not this entity is active. By disabling this, this entity
	 * will not be updated or rendered during the game loop.
	 * 
	 * Default: true
	 *************************************************************************/
	private boolean active = true;
	
	/**************************************************************************
	 * Whether or not this entity will be disposed from its group.
	 * 
	 * Default: true
	 *************************************************************************/
	private boolean immutable = true;
	
	// ========================================================================
	// Constructors
	// ========================================================================
	
	/**************************************************************************
	 * Construct an entity with the specified bounds.
	 * 
	 * @param dimension	the width and height of this entity.
	 * @param location the (x,y) coordinates of this entity.
	 *************************************************************************/
	public Entity(Dimension dimension, Point location) {
		this.dimension = dimension;
		this.location = location;
	}
	
	/**************************************************************************
	 * Construct an entity with the default bounds.
	 *************************************************************************/
	public Entity() {
		this(new Dimension(), new Point());
	}
	
	// ========================================================================
	// Getters & Setters
	// ========================================================================
	
	/**************************************************************************
	 * Whether or not this entity is active. By disabling this, the entity will
	 * not be updated or rendered.
	 * 
	 * @return whether this entity is active or not.
	 *************************************************************************/
	public boolean isActive() {
		return this.active;
	}
	
	/**************************************************************************
	 * Return the depth measure of this entity. This represent the layer at
	 * which this entity will be rendered relative to the screen.
	 * 
	 * @return the layer of this entity.
	 *************************************************************************/
	public int getLayer() {
		return this.layer;
	}
	
	/**************************************************************************
	 * Return the integer value identification for this entity. This 
	 * distinguish the entity from other.
	 * 
	 * @return	the entity ID.
	 *************************************************************************/
	public int getID() {
		return this.id;
	}

	/**************************************************************************
	 * Return whether this entity will be disposed on its group.
	 * 
	 * @return whether or not this entity is immutable.
	 *************************************************************************/
	public boolean isImmutable() {
		return this.immutable;
	}
	
	/**************************************************************************
	 * Sets the active state of this entity.
	 * 
	 * @param active whether or not this entity will be active.
	 *************************************************************************/
	public void setActive(boolean active) {
		this.active = active;
	}
	
	/**************************************************************************
	 * Sets the depth value of this entity.
	 * 
	 * @param layer the new layer for this entity.
	 *************************************************************************/
	public void setLayer(int layer) {
		this.layer = layer;
	}
	
	/**************************************************************************
	 * Sets the integer value identification of this entity.
	 * 
	 * @param id the new id for this entity.
	 *************************************************************************/
	public void setID(int id) {
		this.id = id;
	}
	
	/**************************************************************************
	 * Sets the immutability of this entity.
	 * 
	 * @param immutable whether or not this entity will be immutable.
	 *************************************************************************/
	public void setImmutable(boolean immutable) {
		this.immutable = immutable;
	}
	
	// ========================================================================
	// Override Methods
	// ========================================================================

	@Override
	public double getX() {
		return this.location.getXInt();
	}
	
	@Override
	public double getY() {
		return this.location.getYInt();
	}
	
	@Override
	public int getWidth() {
		return this.dimension.getWidthInt();
	}
	
	@Override
	public int getHeight() {
		return this.dimension.getHeightInt();
	}
	
	@Override
	public void setX(double x) {
		this.location.setX(x);
	}
	
	@Override
	public void setY(double y) {
		this.location.setY(y);
	}
	
	@Override
	public void setWidth(int width) {
		this.dimension.setWidth(width);
	}
	
	@Override
	public void setHeight(int height) {
		this.dimension.setHeight(height);
	}
	
	// ========================================================================
	// Methods
	// ========================================================================

	// ========================================================================
	// Inner & Anonymous Classes
	// ========================================================================
}